package exames;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import medicos.Medico;
import medicos.MedicoNaoEncontradoException;
import medicos.RepositorioMedicos;
import medicos.RepositorioMedicosBDR;
import pacientes.Paciente;
import pacientes.PacienteNaoEncontradoException;
import pacientes.RepositorioPacientes;
import pacientes.RepositorioPacientesBDR;
import util.Data;
import util.PersistenceMechanismException;
import util.PersistenceMechanismRDBMS;
import util.RepositorioException;

public class RepositorioExamesBDR implements RepositorioExames{
	
	private static RepositorioExamesBDR instance;
	private PersistenceMechanismRDBMS pm;
	
	private RepositorioExamesBDR() {
        try {
            pm = PersistenceMechanismRDBMS.getInstance();
            pm.connect();
        }
        catch (Exception ex) {
            //System.out.println(ex.getMessage()); 
            ex.printStackTrace();
        }        
    }

    public synchronized static RepositorioExamesBDR getInstance() {
        if (instance == null) {
            instance = new RepositorioExamesBDR();
        }
        return instance;
    }
    
	public void inserir(Exame exame) throws RepositorioException {
        try {
            Statement statement = (Statement) pm.getCommunicationChannel();
                statement.executeQuery("INSERT INTO EXAMES VALUES ('" +
                                       exame.getCodigo() + "', '" +
                                       exame.getMedico().getCodigo() + "', '" +
                                       exame.getPaciente().getCodigo() + "', '" +
                                       exame.getDescricao() + "', '" +
                                       exame.getResultado() + "', '" +
                                       exame.getDataCadastro() + "')");
        } catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
        } catch (SQLException e) {
            throw new RepositorioException(e);
        } finally {
        	try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
        }
    }
	
	public void remover(long codigo) throws ExameNaoEncontradoException, RepositorioException {
        try{
            Statement statement = (Statement) pm.getCommunicationChannel();
		    int i = statement.executeUpdate("DELETE FROM EXAMES WHERE codigo='" + codigo + "'");
            if (i == 0) {
            	throw new ExameNaoEncontradoException(codigo);
            }
		} catch(PersistenceMechanismException e){
            throw new RepositorioException(e);
		} catch(SQLException e){
            throw new RepositorioException(e);            
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}
	public RepositorioExames procurar(Exame exame) throws RepositorioException{
		IteratorExames exames = this.getIterator();
		RepositorioExames resposta = new RepositorioExamesLista();
		while (exames.hasNext()) {
			Exame e = exames.next();
			if (e.match(exame)){
				resposta.inserir(e);
			} 
		}
		return resposta;
	}
	public Exame procurar(long codigo) throws ExameNaoEncontradoException, RepositorioException {
   	    Exame exame = null;
   	    try {
            Statement statement = (Statement) pm.getCommunicationChannel();
            ResultSet resultset = statement.executeQuery("SELECT * FROM EXAMES WHERE codigo = '" + codigo + "'");
            if (resultset.next()) {
            	RepositorioMedicos rm = RepositorioMedicosBDR.getInstance();
            	Medico medico;
				try {
					medico = rm.procurar(resultset.getLong("fk_medico"));
				} catch (MedicoNaoEncontradoException e) {
					medico = null;
				}
            	RepositorioPacientes rp = RepositorioPacientesBDR.getInstance();
            	Paciente paciente;
				try {
					paciente = rp.procurar(resultset.getLong("fk_paciente"));
				} catch (PacienteNaoEncontradoException e) {
					paciente = null;
				}
				exame = new Exame(resultset.getLong("codigo"),
						  medico,
						  paciente,
					      resultset.getString("descricao"), 
					      resultset.getString("resultado"),
					      new Data(resultset.getString("dataCadastro")));				
            } else {
            	throw new ExameNaoEncontradoException(codigo);
            }
			resultset.close();
		} catch(PersistenceMechanismException e){
            throw new RepositorioException(e);
        } catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return exame;
	}
	public void atualizar(Exame exame) throws ExameNaoEncontradoException, RepositorioException {
	    try {
    	    Statement statement = (Statement) pm.getCommunicationChannel();
            int i = statement.executeUpdate("UPDATE EXAMES SET  medico = '"+exame.getMedico().getCodigo()+
            											 "', paciente = '"+exame.getPaciente().getCodigo()+
            											 "', descricao = '"+exame.getDescricao()+
            											 "', resultado = '"+exame.getResultado()+
            											 "', dataCadastro = '"+exame.getDataCadastro()+" 'WHERE codigo = '" + exame.getCodigo() + "'");
            if (i == 0) {
            	throw new ExameNaoEncontradoException(exame.getCodigo());
            }
		} catch(PersistenceMechanismException e){
            throw new RepositorioException(e);
		} catch (SQLException e) {
		    throw new RepositorioException(e);
	    } finally {
	    	try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}
	public boolean existe(long codigo) throws RepositorioException {
        boolean resposta = false;
        try {
            Statement statement = (Statement) pm.getCommunicationChannel();
            ResultSet resultset = statement.executeQuery("SELECT * FROM EXAMES WHERE codigo = '" + codigo + "'");
            resposta = resultset.next();
			resultset.close();
		} catch(PersistenceMechanismException e){
            throw new RepositorioException(e);
        } catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
        return resposta;
    }
	
	public RepositorioExames getExames() throws RepositorioException {
        RepositorioExames resposta = new RepositorioExamesLista();
        try {
            Statement statement = (Statement) pm.getCommunicationChannel();
            ResultSet resultset = statement.executeQuery("SELECT * FROM EXAMES");
            while (resultset.next()) {
            	RepositorioMedicos rm = RepositorioMedicosBDR.getInstance();
            	Medico medico;
				try {
					medico = rm.procurar(resultset.getLong("fk_medico"));
				} catch (MedicoNaoEncontradoException e) {
					medico = null;
				}
            	RepositorioPacientes rp = RepositorioPacientesBDR.getInstance();
            	Paciente paciente;
				try {
					paciente = rp.procurar(resultset.getLong("fk_paciente"));
				} catch (PacienteNaoEncontradoException e) {
					paciente = null;
				}
				Exame exame= new Exame(resultset.getLong("codigo"),
         				  medico,
           				  paciente,
           		          resultset.getString("descricao"), 
           		          resultset.getString("resultado"),
           		          new Data(resultset.getString("dataCadastro")));
                resposta.inserir(exame);
            }
			resultset.close();
		} catch(PersistenceMechanismException e){
            throw new RepositorioException(e);
        } catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
        return resposta;
    }
	public IteratorExames getIterator() throws RepositorioException {
        return this.getExames().getIterator();
    }

}
